import json
import time

from django.core.management import call_command
from django.db import connection, transaction
from django.test import TestCase, TransactionTestCase

from main import models


def execute(sql, params=()):
    # with transaction.atomic():
    with connection.cursor() as cursor:
        cursor.execute(sql, params=params)
        return cursor.fetchall()


class TestDB(TransactionTestCase):
    @classmethod
    def setUpClass(cls):
        call_command('make_data')

    def test(self):
        sql_job = 'SELECT job_id, config FROM timescaledb_information.jobs WHERE proc_name = %s AND scheduled'
        sql_chunks = 'SELECT chunk_name FROM timescaledb_information.chunks WHERE hypertable_name = %s and is_compressed'
        sql_add_retention = 'SELECT add_retention_policy(%s, INTERVAL %s)'
        sql_del_retention = 'SELECT remove_retention_policy(%s)'
        sql_data_table = f'SELECT id FROM {models.SimpleTable._meta.db_table}'

        rows = execute(sql_job, params=('policy_compression',))
        self.assertTrue(json.loads(rows[0][1])['compress_after'] == '00:01:00')
        self.assertTrue(len(rows) == 1)

        rows = execute(sql_chunks, params=(models.SimpleTable._meta.db_table,))
        self.assertTrue(len(rows) == 0)

        time.sleep(60 * 3)

        rows = execute(sql_chunks, params=(models.SimpleTable._meta.db_table,))
        self.assertTrue(len(rows) > 0)

        rows = execute(sql_data_table)
        row_count = len(rows)
        self.assertTrue(row_count > 0)

        execute(sql_add_retention, params=(models.SimpleTable._meta.db_table, '1 min'))

        rows = execute(sql_job, params=('policy_retention',))
        self.assertTrue(json.loads(rows[0][1])['drop_after'] == '00:01:00')
        self.assertTrue(len(rows) == 1)

        time.sleep(60 * 1)

        rows = execute(sql_data_table)
        self.assertTrue(len(rows) < row_count)

        execute(sql_del_retention, params=(models.SimpleTable._meta.db_table,))

        rows = execute(sql_job, params=('policy_retention',))
        self.assertTrue(len(rows) == 0)
